home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / src.arc / AX25USER.C < prev    next >
C/C++ Source or Header  |  1989-08-07  |  5KB  |  218 lines

  1. /* User subroutines for AX.25 */
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "timer.h"
  5. #include "iface.h"
  6. #include "lapb.h"
  7. #include "ax25.h"
  8. #include "lapb.h"
  9. #include <ctype.h>
  10.  
  11. /* Open an AX.25 connection */
  12. struct ax25_cb *
  13. open_ax25(iface,local,remote,mode,window,r_upcall,t_upcall,s_upcall,user)
  14. struct iface *iface;        /* Interface */
  15. struct ax25_addr *local;    /* Local address */
  16. struct ax25_addr *remote;    /* Remote address */
  17. int mode;            /* active/passive/server */
  18. int16 window;            /* Window size in bytes */
  19. void (*r_upcall)();        /* Receiver upcall handler */
  20. void (*t_upcall)();        /* Transmitter upcall handler */
  21. void (*s_upcall)();        /* State-change upcall handler */
  22. int user;            /* User linkage area */
  23. {
  24.     struct ax25_cb *axp;
  25.     struct ax25_addr remtmp;
  26.  
  27.     if(remote == NULLAXADDR){
  28.         remote = &remtmp;
  29.         setcall(remote," ");
  30.     }
  31.     if((axp = find_ax25(remote)) != NULLAX25 && axp->state != DISCONNECTED)
  32.         return NULLAX25;    /* Only one to a customer */
  33.     if(axp == NULLAX25 && (axp = cr_ax25(remote)) == NULLAX25)
  34.         return NULLAX25;
  35.     ASSIGN(axp->remote,*remote);
  36.     ASSIGN(axp->local,*local);
  37.     axp->iface = iface;
  38.     axp->window = window;
  39.     axp->r_upcall = r_upcall;
  40.     axp->t_upcall = t_upcall;
  41.     axp->s_upcall = s_upcall;
  42.     axp->user = user;
  43.  
  44.     switch(mode){
  45.     case AX_SERVER:
  46.         axp->flags.clone = 1;
  47.     case AX_PASSIVE:    /* Note fall-thru */
  48.         axp->state = LISTEN;
  49.         return axp;
  50.     case AX_ACTIVE:
  51.         break;
  52.     }    
  53.     switch(axp->state){
  54.     case DISCONNECTED:
  55.         est_link(axp);
  56.         lapbstate(axp,SETUP);
  57.         break;
  58.     case SETUP:
  59.         free_q(&axp->txq);
  60.         break;
  61.     case DISCPENDING:    /* Ignore */
  62.         break;
  63.     case RECOVERY:
  64.     case CONNECTED:
  65.         free_q(&axp->txq);
  66.         est_link(axp);
  67.         lapbstate(axp,SETUP);
  68.         break;
  69.     }
  70.     return axp;
  71. }
  72.  
  73. /* Send data on an AX.25 connection. Caller provides optional PID. If
  74.  * a PID is provided, then operate in stream mode, i.e., a large packet
  75.  * is automatically packetized into a series of paclen-sized data fields.
  76.  *
  77.  * If pid == -1, it is assumed the packet (which may actually be a queue
  78.  * of distinct packets) already has a PID on the front and it is passed
  79.  * through directly even if it is very large.
  80.  */
  81. int
  82. send_ax25(axp,bp,pid)
  83. struct ax25_cb *axp;
  84. struct mbuf *bp;
  85. int pid;
  86. {
  87.     struct mbuf *bp1;
  88.     int16 offset,len,size;
  89.  
  90.     if(axp == NULLAX25 || bp == NULLBUF)
  91.         return -1;
  92.  
  93.     if(pid != -1){
  94.         offset = 0;
  95.         len = len_mbuf(bp);
  96.         /* It is important that all the pushdowns be done before
  97.          * any part of the original packet is freed.
  98.          * Otherwise the pushdown might erroneously overwrite
  99.          * a part of the packet that had been duped and freed.
  100.          */
  101.         while(len != 0){
  102.             size = min(len,axp->paclen);
  103.             dup_p(&bp1,bp,offset,size);
  104.             len -= size;
  105.             offset += size;
  106.             bp1 = pushdown(bp1,1);
  107.             bp1->data[0] = pid;
  108.             enqueue(&axp->txq,bp1);
  109.         }
  110.         free_p(bp);
  111.     } else {
  112.         enqueue(&axp->txq,bp);
  113.     }
  114.     return lapb_output(axp);
  115. }
  116.  
  117. /* Receive incoming data on an AX.25 connection */
  118. struct mbuf *
  119. recv_ax25(axp,cnt)
  120. struct ax25_cb *axp;
  121. int16 cnt;
  122. {
  123.     struct mbuf *bp;
  124.  
  125.     if(axp->rxq == NULLBUF)
  126.         return NULLBUF;
  127.  
  128.     if (cnt == 0) { /* This means we want it all */
  129.         bp = axp->rxq;
  130.         axp->rxq = NULLBUF;
  131.     }
  132.     else {
  133.         if((bp = alloc_mbuf(cnt)) == NULLBUF)
  134.             return NULLBUF;
  135.         bp->cnt = pullup(&axp->rxq,bp->data,cnt);
  136.     }
  137.     /* If this has un-busied us, send a RR to reopen the window */
  138.     if(len_mbuf(axp->rxq) < axp->window
  139.        && (len_mbuf(axp->rxq) + bp->cnt) >= axp->window)
  140.         sendctl(axp,RESPONSE,RR);
  141.  
  142.     return bp;
  143. }
  144.  
  145. /* Close an AX.25 connection */
  146. int
  147. disc_ax25(axp)
  148. struct ax25_cb *axp;
  149. {
  150.     if(axp == NULLAX25)
  151.         return -1;
  152.     switch(axp->state){
  153.     case DISCONNECTED:
  154.         break;        /* Ignored */
  155.     case LISTEN:
  156.         del_ax25(axp);
  157.         break;
  158.     case DISCPENDING:
  159.         lapbstate(axp,DISCONNECTED);
  160.         break;
  161.     case CONNECTED:
  162.     case RECOVERY:
  163.         free_q(&axp->txq);
  164.         axp->retries = 0;
  165.         sendctl(axp,COMMAND,DISC|PF);
  166.         stop_timer(&axp->t3);
  167.         start_timer(&axp->t1);
  168.         lapbstate(axp,DISCPENDING);
  169.         break;
  170.     }
  171.     return 0;
  172. }
  173.  
  174. /* Verify that axp points to a valid ax25 control block */
  175. int
  176. ax25val(axp)
  177. struct ax25_cb *axp;
  178. {
  179.     register struct ax25_cb *axp1;
  180.     register int i;
  181.  
  182.     if(axp == NULLAX25)
  183.         return 0;    /* Null pointer can't be valid */
  184.     for(i=0; i < NHASH; i++)
  185.         for(axp1 = Ax25_cb[i];axp1 != NULLAX25; axp1 = axp1->next)
  186.             if(axp1 == axp)
  187.                 return 1;
  188.     return 0;
  189. }
  190.  
  191. /* Force a retransmission */
  192. int
  193. kick_ax25(axp)
  194. struct ax25_cb *axp;
  195. {
  196.     if(!ax25val(axp))
  197.         return -1;
  198.     recover(axp);
  199.     return 0;
  200. }
  201.  
  202. /* Abruptly terminate an AX.25 connection */
  203. int
  204. reset_ax25(axp)
  205. struct ax25_cb *axp;
  206. {
  207.     void (*upcall)();
  208.  
  209.     if(axp == NULLAX25)
  210.         return -1;
  211.     upcall = axp->s_upcall;
  212.     lapbstate(axp,DISCONNECTED);
  213.     /* Clean up if the standard upcall isn't in use */
  214.     if(upcall != s_ascall)
  215.         del_ax25(axp);
  216.     return 0;
  217. }
  218.